package pac

import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"time"

	db "slgw_web/application/gormdb"
	"slgw_web/serial/dto"
	"slgw_web/serial/util"

	models "openzbox.com/frame/echo/models/sl_gw01"
)

// 字符串转为16进制
func EncodeToString(inputStr string) string {
	byte_data := []byte(inputStr)
	// 将 byte 装换为 16进制的字符串
	hex_string_data := hex.EncodeToString(byte_data)
	// byte 转 16进制 的结果
	return string(hex_string_data)
}

// 16进制转为字符串
func DecodeToString(inputStr string) string {
	bytes, err := hex.DecodeString(inputStr)
	if err != nil {
		util.Error("DecodeToString错误:" + err.Error())
	}
	return string(bytes)
}

// 十进制转十六进制
func ToHex(data int64) string {
	Hex := fmt.Sprintf("%x", data)
	return Hex
}

// 十进制转十六进制
func HexToDec(val string) int {
	n, err := strconv.ParseUint(val, 16, 32)
	if err != nil {
		fmt.Println("HexToDec错误" + err.Error())
	}
	return int(n)
}

// 补足十六进制的0位数
func FourZero(str string) string {
	str0 := ""
	if len(str) < 4 {
		for i := 0; i < 4-len(str); i++ {
			str0 += "0"
		}
		return str0 + str
	} else {
		return str
	}
}

// 时间戳转为时间 -8小时 时区
func TimeStampToTime(TimeStamp int) string {
	//时间日期格式模板
	timeTemplate := "2006-01-02 15:04:05"
	time2 := time.Unix(int64(TimeStamp), 0)
	tm := time2.In(time.UTC)
	timeStr := tm.Format(timeTemplate)
	return timeStr
}

func CalculateChecksum(input string) string {
	// 将输入字符串解析为字节数组
	inputBytes := make([]byte, len(input)/2)
	for i := 0; i < len(inputBytes); i++ {
		fmt.Sscanf(input[2*i:2*i+2], "%02X", &inputBytes[i])
	}
	// 计算校验值
	var checksum byte
	for _, b := range inputBytes {
		checksum += b
	}
	// 将校验值转换为 16 进制字符串输出
	checksumHex := fmt.Sprintf("%02X", checksum)
	return checksumHex
}

// 心跳包请求
func Task2(deviced string, sb models.DeviceInfo) {
	timeout := time.Duration(sb.OHRT)
	//fmt.Println("心跳包请求", sb.OHRT)
	if sb.ApplicationLayerProtocol == 1 {
		serialNum := deviced
		var topStr = "68000768"
		var firstStr = "03"
		var hexStr = CalculateChecksum(firstStr + serialNum)
		var inputInfo = topStr + firstStr + serialNum + hexStr + "16"
		CreateTimer(sb.DeviceInfoID+util.Task1, timeout*time.Second, inputInfo, 0, sb, nil, nil)
	} else if sb.ApplicationLayerProtocol == 2 {
		//dtu心跳包
		if sb.OHRTCode == nil {
			util.Error("心跳包请求失败:" + sb.Name + "的自定义心跳包数据不能为空")
		} else {
			inputInfo := *sb.OHRTCode
			CreateTimer(sb.DeviceInfoID+util.Task1, timeout*time.Second, inputInfo, 4, sb, nil, nil)
		}
	} else if sb.ApplicationLayerProtocol == 6 {
		paramsC := make([][]byte, 0)
		for _, c := range util.DeviceInfo_Concentrator {
			if c.Device_ID == sb.ID {
				//发送心跳包
				params := make(map[string]interface{})
				sendData := util.Concentrator_SendData{Func: 2, Dev: c.Dev, Data: params}
				jsonData, err3 := json.Marshal(sendData)
				if err3 != nil {
					util.Error(sb.Name + ",dev:" + c.Dev + "心跳包序列化失败,err:" + err3.Error())
					continue
				} else {
					paramsC = append(paramsC, jsonData)
				}

			}
		}
		CreateTimer(sb.DeviceInfoID+util.Task1, timeout*time.Second, "", 10, sb, nil, &paramsC)

	}
}

// 查询DeviceInfo参数
func GetDeviceParameters() []models.DeviceInfo {
	deviceInfo := []models.DeviceInfo{}
	db := db.GetDB()
	//查询所有文章,以及文章的分类Preload
	db.Find(&deviceInfo)
	return deviceInfo
}

// 判断参数是否已存在
func IsParameterExists(param dto.Parameter, existingData []dto.Parameter) bool {
	for _, existingParam := range existingData {
		if param.Description == existingParam.Description &&
			param.Code == existingParam.Code &&
			param.Value == existingParam.Value {
			return true
		}
	}
	return false
}

// 去重
func RemoveDuplicates(s []int64) []int64 {
	encountered := map[int64]bool{}
	result := []int64{}

	for _, item := range s {
		if !encountered[item] {
			encountered[item] = true
			result = append(result, item)
		}
	}

	return result
}
func GetModbusData[T any](results []T) string {
	hexString := ""
	for _, item := range results {
		str1 := fmt.Sprintf("%04X", item) //转成16进制
		hexString += str1
	}
	return hexString
}
func Ab2hex(buffer []byte) string {
	hexArr := make([]string, len(buffer))
	for i, bit := range buffer {
		hexArr[i] = fmt.Sprintf("%02X", bit)
	}
	return strings.Join(hexArr, "")
}

// 初始化地址位
func initAdress() string {
	str := strings.Repeat("0000", 146) //NEW:第148点号 OLD(44:E24 写42)
	return str
	// return splitString(str, 4)

}
func initAdressError() string {
	str := strings.Repeat("EEEE", 146) //NEW:第148点号 OLD(44:E24)
	return str
}

// 将字符串按照指定位数分割为数组
func splitString(str string, groupSize int) []string {
	//var chunks []string
	chunks := make([]string, 0, (len(str)+groupSize-1)/groupSize)
	for i := 0; i < len(str); i += groupSize {
		end := i + groupSize
		if end > len(str) {
			end = len(str)
		}
		chunk := str[i:end]
		chunks = append(chunks, chunk)
	}
	return chunks
}

func GetCOMName(name string, comType int) string {
	if comType == 1 {
		switch name {
		case "/dev/ttyS8":
			return "COM1"
		case "/dev/ttyS3":
			return "COM2"
		case "/dev/ttyS7":
			return "COM3"
		case "/dev/ttyS6":
			return "COM4"
		case "/dev/ttyS4":
			return "COM5"
		case "/dev/ttyS5":
			return "COM6"
		case "/dev/ttyS9":
			return "COM7"
		case "/dev/ttyS2":
			return "COM8"
		default:
			return name
		}
	}
	switch name {
	case "/dev/ttyS1":
		return "COM1"
	case "/dev/ttyS2":
		return "COM2"
	case "/dev/ttyS3":
		return "COM3"
	case "/dev/ttyS4":
		return "COM4"
	default:
		return name
	}
}

func GetDeviceName(comPort string, comType int) string {
	if comType == 1 {
		switch comPort {
		case "COM1":
			return "/dev/ttyS8"
		case "COM2":
			return "/dev/ttyS3"
		case "COM3":
			return "/dev/ttyS7"
		case "COM4":
			return "/dev/ttyS6"
		case "COM5":
			return "/dev/ttyS4"
		case "COM6":
			return "/dev/ttyS5"
		case "COM7":
			return "/dev/ttyS9"
		case "COM8":
			return "/dev/ttyS2"
		default:
			return "error"
		}
	}

	switch comPort {
	case "COM1":
		return "/dev/ttyS1"
	case "COM2":
		return "/dev/ttyS2"
	case "COM3":
		return "/dev/ttyS3"
	case "COM4":
		return "/dev/ttyS4"
	default:
		return "error"
	}
}
